package com.taoyun.service.impl;

import com.taoyun.mapper.*;
import com.taoyun.pojo.entity.FileBelongGroup;
import com.taoyun.pojo.entity.User;
import com.taoyun.pojo.vo.UserVO;
import com.taoyun.service.IFileService;
import com.taoyun.service.IObsService;
import com.taoyun.service.IUserService;
import com.taoyun.utils.ExcelUtils;
import com.taoyun.utils.MD5;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 业务汇总：
 *      登录
 *
 *      重置密码
 *
 *      批量添加员工
 *
 *      批量删除员工
 *
 *      超管更改管理员、管理员更改部门内员工信息
 *      员工更新个人信息
 *      修改密码
 *
 *      根据ID查找员工
 *      根据姓名模糊查询员工
 *      查询部门内员工
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IFileService fileService;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private IObsService obsService;

    @Autowired
    private USendFMapper uSendFMapper;

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private FileBelongGroupMapper fileBelongGroupMapper;

    @Override
    public User login(String userNumber, String password) {
        return userMapper.login(userNumber,password);
    }

    @Override
    public boolean resetPassword(String userNumber, String email, String newPassword) {
        return userMapper.resetPassword(userNumber,email,newPassword);
    }

    @Override
    public boolean modifyPassword(String userNumber, String newPassword) {
        return userMapper.modifyPassword(userNumber,newPassword);
    }

    @Override
    public boolean updateEmail(String userNumber, String newEmail) {
        return userMapper.updateEmail(userNumber,newEmail);
    }

    @Override
    public User findUser(Integer id) {
        return null;
    }

//    //
//    @Override
//    public User getUserById(Integer id) {
//        return null;
//    }


//    /**
//     * 批量添加员工
//     * @param users
//     * @return
//     */
//    @Override
//    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
//    public int AddStaffsBatch(List<User> users) {
//        for(User user :users){
//            //密码加密
//            user.setPassword(MD5.stringMD5(user.getPassword()));
//        }
//        return userMapper.AddStaffsBatch(users);
//    }


//    /**
//     * 根据id批量删除员工
//     * @param ids
//     * @return
//     */
//    @Override
//    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
//    public Integer DeleteStaffsBatch(String ids) {
//        //判断是否为空，空返回0
//        if(!ids.equals("")){
//            //将字符串转为整型数组
//            List<Integer> idlist = Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toList());
//            int result =  userMapper.DeleteStaffsBatch(idlist);
//            if(result != 0){
//                //删除成功返回1
//                return 1;
//            }else{
//                //删除失败返回-1
//                return -1;
//            }
//        }else {
//            //参数为空返回0
//            return 0;
//        }
//    }

//    /**
//     * 根据id查找员工
//     * @param id
//     * @return
//     */
//    @Override
//    public User SearchStaffByID(Integer id) {
//        return userMapper.SearchStaffByID(id);
//    }

    /**
     * 通过账号以及邮箱查找用户信息
     * @param userNumber 账号
     * @param email 邮箱
     * @return
     */
    @Override
    public User searchByEmailAndUserNumber(String userNumber, String email) {
        return userMapper.searchByEmailAndUserNumber(userNumber,email);
    }


//    /**
//     * 根据姓名对员工的模糊查询
//     * @param name
//     * @return
//     */
//    @Override
//    public List<User> SearchStaffByName(String name) {
//        return userMapper.SearchStaffByName(name);
//    }


//    /**
//     * 超管更改管理员、员工\管理员更改员工信息（姓名、性别、部门、权限、状态）
//     * @param admin_id  操作者id
//     * @param user      提交的更改对象的信息
//     * @return
//     */
//    @Override
//    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
//    public Integer AdminChangeStaffState(Integer admin_id, User user) {
//            //获取操作者权限和所在部门
//            User operator = userMapper.SearchStaffByID(admin_id);
//            String o_permission =operator.getPermission();
//            String o_department = operator.getDepartment();
//            //获取被操作者权限和所在部门
//            User byoperator = userMapper.SearchStaffByID(user.getUserId());
//            String b_permission = byoperator.getPermission();
//            String b_department = byoperator.getDepartment();
//            //验证两者权限高低,当管理员更改员工状态时，须验证两者是否属于同一部门
//            if(      (o_permission.equals("超管") && b_permission.equals("管理员")) ||
//                    (o_permission.equals("超管") && b_permission.equals("员工"))   ||
//                    (o_permission.equals("管理员") && b_permission.equals("员工")) && o_department.equals(b_department) ){
//                return userMapper.AdminChangeStaffState(user);
//            }else{
//                //不符合以上权限则不予更改，返回0
//                return 0;
//            }
//    }



//    /**
//     * 查询部门所有员工
//     * @param dname
//     * @return
//     */
//    @Override
//    public List<User> SearchStaffByDepartment(String dname) {
//            return userMapper.SearchStaffByDepartment(dname);
//    }

//      添加单个员工（测试）
//    @Override
//    public int AddAdmin(User user) {
//        user.setPassword(MD5.stringMD5(user.getPassword()));
//        return userMapper.AddAdmin(user);
//    }

//    /**
//     *  个人信息管理（包括超管、管理员、员工），只能修改密码，邮箱。手机号
//     * @param user
//     * @return
//     */
//    @Override
//    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
//    public Integer UpdateStaffs(User user) {
//        return userMapper.UpdateStaffs(user);
//    }

//    /**
//     * 修改密码
//     * @param userId    操作者id
//     * @param password  新密码
//     * @param email     验证邮箱
//     * @return
//     */
//    @Override
//    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
//    public Integer StaffUpdatePwd(Integer userId, String password, String email) {
//        User user = userMapper.SearchStaffByID(userId);
//        //获取用户存放在数据库中的邮箱
//        String old_email = user.getEmail();
//        //判断邮箱是否正确
//        if(old_email.equals(email)){
//            return userMapper.StaffUpdatePwd(userId, MD5.stringMD5(password));
//        }else {
//            return 0;
//        }
//    }



    //
    @Override
    public User getUserById(Integer id) {
        return userMapper.SearchStaffByID(id);
    }

    /**
     * 超管查询全部用户
     * @return List<User> userList
     */
    @Override
    public List<User> ShowAll(Integer Id){return userMapper.ShowAll(Id);}

    /**
     * 超管添加管理员之前先查询该部门是否已设置管理员
     * @param department
     * @return Integer
     */
    @Override
    public List<User> AdminExist(String department, String permission){
        List<User> Admins = userMapper.AdminExist(department, permission);
        return Admins;
    }

    /**
     * 删除员工信息
     * @Param id
     * @return Integer
     */
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer DeleteUser(Integer userId){
        String userNumber = userMapper.SearchStaffByID(userId).getUserNumber();
        //先删除其他从表与关联表
        if(deleteUserFile(userId, userNumber)){
            //删除user表记录
            int deleteResult = userMapper.DeleteUser(userId);
            if(deleteResult == 1){
                //删除员工后立即删除他的所属obs文件
                if(obsService.delete_Obsobject("user/" + userNumber + "/") == 1){
                    return 1;
                }else{
                    return 0;
                }
            }else {
                return 0;
            }
        }else {
            return 0;
        }
    }

    /**
     * 超管批量删除员工
     * @Param Integer[] ids
     * @return Integer
     */
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer DeleteUserBatch(Integer[] ids){
        boolean deleteResult = false;
        for (Integer userId : ids) {
            String userNumber = userMapper.SearchStaffByID(userId).getUserNumber();
            deleteResult = deleteUserFile(userId, userNumber);
            //删除obs文件夹
            //删除员工后立即删除他的所属obs文件
            if(deleteResult && obsService.delete_Obsobject("user/" + userNumber + "/") == 1){
                deleteResult = true;
            }else{
                deleteResult = false;
            }
        }
        if(deleteResult){
            if(userMapper.DeleteUserBatch(ids) == ids.length){
                return 1;
            }else{
                return 0;
            }
        }else {
            return 0;
        }
    }

    /**
     *  删除员工时同时删除obs文件与相关数据库文件记录
     * @param userId userId
     */
    public Boolean deleteUserFile(Integer userId, String userNumber){
        //获取用户所属文件的id列表和userNumber
        List<Integer> fileIds = uSendFMapper.selectFileIdsByUId(userId);
        //先删除从表U_send_F以及ObjectSize
        uSendFMapper.deleteByUId(userId);
        fileMapper.delete_ObjectSize("user/" + userNumber + "/");
//        //如果该用户加入了（多个）群组，则先删除该用户在群组的记录
//        List<Integer> gIdList = groupMapper.SelectGIdsByUId(userId);
//        if(gIdList.size() > 0){
//            //删除group表的记录
//            groupMapper.DeleteGByUId(userId);
//        }
        //再删除主表file，只删除用户的个人文件记录，不删除用户上传到群组的文件记录
        Integer deleteCount = fileMapper.deleteFileBatchs(fileIds);
        if(deleteCount == fileIds.size()){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 超管修改员工信息
     * @Param User user
     * @return Integer
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer SAdminModify(User user){
        if(userMapper.SAdminModify(user)==1){
            return 1;
        }else{
            return 0;
        }
    }

    /**
     * 超管重置密码
     * @Param AdminId
     * @return Integer
     */
    public Integer ResetAllPassword(Integer AdminId){
        if(userMapper.SearchStaffByID(AdminId) != null){  //先判断有没有该用户
            User u = userMapper.SearchStaffByID(AdminId);
            if(u.getPermission().equals("超管")){ //判断是不是超管身份
                String Pass = "";
                userMapper.ResetAllPassword(MD5.stringMD5(Pass));
                return 1; //重置密码成功
            }else{
                return -1; //不是超管
            }
        }else{
            return 0; //没有该用户，无法判断
        }
    }

    /**
     * 批量添加员工
     * @param users
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer AddStaffsBatch(List<User> users) throws IOException {
        boolean result = false;
        for(User user : users){
            //密码加密
            user.setPassword(MD5.stringMD5(user.getPassword()));
        }
        Integer count = userMapper.AddStaffsBatch(users);
        if(users.size() == count){
            for(User user : users){
                //获取userId的方式可以在XML进行循环插入时通过回写自增id进行优化
                Integer userId = userMapper.SearchUserByNumber(user.getUserNumber()).getUserId();
                result = obsService.putObject("user/" + user.getUserNumber(), user.getName(), "user", userId);
                if(!result){
                    break;
                }
            }
            return count;
        }else {
            return -1;
        }
    }

    /**
     * 单个添加员工
     * @param user
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer AddUser(User user) throws IOException {
        user.setPassword(MD5.stringMD5(user.getPassword()));
        if(userMapper.AddUser(user) == 1) {
            boolean result = obsService.putObject("user/" + user.getUserNumber(), user.getName(), "user", user.getUserId());
            if (result) {
                return 1;
            } else {
                return -1;
            }
        } else{
            //添加失败返回-1
            return -1;
        }
    }

    /**
     * 根据id批量删除员工
     * @param ids
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer DeleteStaffsBatch(String ids) {
        //判断是否为空，空返回0
        if(!ids.equals("")){
            //将字符串转为整型数组
            List<Integer> idlist = Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toList());
            for (Integer id : idlist) {
//                deleteUserFile(id);
            }
            int result =  userMapper.DeleteStaffsBatch(idlist);
            if(result != 0){
                //删除成功返回1
                return 1;
            }else{
                //删除失败返回-1
                return -1;
            }
        }else {
            //参数为空返回0
            return 0;
        }
    }


    /**
     * 根据邮箱查找员工
     * @param email 邮箱
     * @return 员工
     */
    @Override
    public User SearchStaffByEmail(String email) {
        return userMapper.SearchStaffByEmail(email);
    }

    /**
     * 根据姓名对员工的模糊查询
     * @param name
     * @return
     */
    @Override
    public List<User> SearchStaffByName(String name,String Department) {
        return userMapper.SearchStaffByName(name,Department);
    }


    /**
     * 超管更改管理员、员工\管理员更改员工信息（姓名、性别、部门、权限、状态）
     * @param admin_id  操作者id
     * @param user      提交的更改对象的信息
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer AdminChangeStaffState(Integer admin_id, User user) {
        //获取操作者权限和所在部门
        User operator = userMapper.SearchStaffByID(admin_id);
        String o_permission =operator.getPermission();
        String o_department = operator.getDepartment();
        //获取被操作者权限和所在部门
        User byoperator = userMapper.SearchStaffByID(user.getUserId());
        String b_permission = byoperator.getPermission();
        String b_department = byoperator.getDepartment();
        //验证两者权限高低,当管理员更改员工状态时，须验证两者是否属于同一部门
        if(      (o_permission.equals("超管") && b_permission.equals("管理员")) ||
                (o_permission.equals("超管") && b_permission.equals("员工"))   ||
                (o_permission.equals("管理员") && b_permission.equals("员工")) && o_department.equals(b_department) ){
            return userMapper.AdminChangeStaffState(user);
        }else{
            //不符合以上权限则不予更改，返回0
            return 0;
        }
    }



    /**
     * 查询部门所有员工
     * @param dname
     * @return
     */
    @Override
    public List<User> SearchStaffByDepartment(String dname) {
        return userMapper.SearchStaffByDepartment(dname);
    }


    /**
     *  个人信息管理（包括超管、管理员、员工），只能修改密码，邮箱。手机号
     * @param userVO
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer UpdateStaffs(UserVO userVO) {
        return userMapper.UpdateStaffs(userVO);
    }

    /**
     * 修改密码
     * @param userId    操作者id
     * @param password  新密码
     * @param email     验证邮箱
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public Integer StaffUpdatePwd(Integer userId, String password, String email) {
        User user = userMapper.SearchStaffByID(userId);
        //获取用户存放在数据库中的邮箱
        String old_email = user.getEmail();
        //判断邮箱是否正确
        if(old_email.equals(email)){
            return userMapper.StaffUpdatePwd(userId, MD5.stringMD5(password));
        }else {
            return 0;
        }
    }

    /**
     * 管理员添加员工时，判断是否添加在自己部门，不能添加别的部门的员工
     * @Param
     * @Return
     */
    @Override
    public Boolean SameDepartment(Integer AdminId, String userDepartment){
        User Admin = userMapper.SearchStaffByID(AdminId);
        if(Admin.getDepartment().equals(userDepartment)){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 通过UserNumberList查找员工
     * @param users
     * @return Integer
     */
    @Override
    public Integer SelectUserByUserNumberList(List<User> users){
        int result = 0;
        for(User user:users) {
            if (userMapper.SelectUserByUserNumber(user.getUserNumber()) != null){
                result = 1;
                break;
            }
        }
        return result;
    }

    /**
     * 通过UserNumber查找员工
     * @param userNumber
     * @return int
     */
    @Override
    public Integer SelectUserByUserNumber(String userNumber){
        if(userMapper.SelectUserByUserNumber(userNumber)==null){
            return 0;  //不存在返回0
        }else{
            return 1;
        }
    }

    /**
     * 数据验证，验证必要信息是否符合规范
     * @param users
     * @return ErrorMap
     */
    @Override
    public Map<String,String> NoNUll(List<User> users, HttpServletResponse response){
        Map<String ,String> ErrorMap = new HashMap<>();   //存储错误信息
        //List<Integer> ErrorUsersList = new ArrayList<Integer>();   //讲不规范的信息放在ErrorUserList列表，然后export到excel表到桌面
        List<User> ErrorUserList = new ArrayList<User>();
        Set<Integer> ErrorList = new HashSet<Integer>();
        String PhoneNumberRegex = "^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$";
        String EmailRegex = "\"^\\\\s*\\\\w+(?:\\\\.{0,1}[\\\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\\\.[a-zA-Z]+\\\\s*$\"";
        for(int i = 0; i< users.size(); i++){
            if(users.get(i).getUserNumber().equals("")) {
                ErrorMap.put("userNumber_ErrorMsg", "用户工号不能为空。");
                ErrorList.add(i);  //将不符合规范的信息的下标存在错误列表
            }
            if(users.get(i).getName().equals("")) {
                ErrorMap.put("Name_ErrorMsg", "名字不能为空。");
                ErrorList.add(i);
            }
            if(users.get(i).getPhoneNumber().equals("")) {
                ErrorMap.put("PhoneNumber_ErrorMsg", "电话号码不能为空");
                ErrorList.add(i);
            }
            if(!((users.get(i).getPhoneNumber()).matches(PhoneNumberRegex))) {
                ErrorMap.put("电话号码格不正确", "需要11位");
                ErrorList.add(i);
            }
            if(users.get(i).getEmail().equals("")) {
                ErrorMap.put("Email_ErrorMsg", "邮箱不能为空！");
                ErrorList.add(i);
            }
            if(!((users.get(i).getEmail()).matches(EmailRegex))) {
                ErrorMap.put("Email_ErrorMsg", "邮箱格式不正确！");
                ErrorList.add(i);
            }
            //return ErrorMap;
        }
        if(!ErrorList.isEmpty() && ErrorList.size()!=0){
            Iterator<Integer> it = ErrorList.iterator();
            User ErrorUser = new User();
            while(it.hasNext()){
                ErrorUser = userMapper.SearchStaffByID(it.next());
                ErrorUserList.add(ErrorUser);
            }
            ExcelUtils.exportExcel(ErrorUserList,"错误信息","错误Sheet",User.class,"错误", response);
        }
        if(ErrorMap.isEmpty() && ErrorMap.size()==0)  //如果ErrorMap为空，表明没有错误
            ErrorMap.put("数据验证结果", "没有错误。");
        return ErrorMap;
    }

    /**
     * 超管批量允许用户使用云盘
     * @param Ids
     * @return Integer
     */
    @Override
    public Integer AllowState(List<Integer> Ids){
        return userMapper.AllowState(Ids);
    }

    /**
     * 超管批量禁止用户使用云盘
     * @param Ids
     * @return Integer
     */
    @Override
    public Integer BanState(List<Integer> Ids){
        return userMapper.BanState(Ids);
    }

    /**
     * 超管降职管理员为员工
     * @param Department
     * @return Integer
     */
    @Override
    public Integer Demotion(String Department){
        User user = userMapper.GetDepartmentAdmin(Department);
        userMapper.Demotion(user.getUserId());
        return 1;
    }

    /**
     * 超管提升员工为管理员
     * @param userId
     * @return Integer
     */
    @Override
    public Integer Promoted(Integer userId){
        if(userMapper.Promoted(userId)==1)
            return 1;
        return 0;
    }

}
